/*
*    Phantom v2.0 GUI Automation Software
*    Copyright (C) 2009  John C. Van Arsdall (john@phantomtest.com)
*
*    This program is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License along
*    with this program; if not, write to the Free Software Foundation, Inc.,
*    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
// Status.cpp: implementation of the CStatus class.
//
//////////////////////////////////////////////////////////////////////

#include "ssi_status.h"
#include "ssi_status.h"
#include <stdarg.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

SSI_SCRIPTDLL_API SSI_INT64 CStatus::ErrCount = 0;
SSI_SCRIPTDLL_API SSI_INT64 CStatus::WarnCount = 0;

CStatus::CStatus()
{
  State = sOK;
}

CStatus::CStatus(SSI_BYTE NewState, const String& NewMessage, const SSI_CHAR bDoIncr) 
{
  State = NewState;
  Message = NewMessage;

	if(bDoIncr){
		IncrementCounts();
	}
}

CStatus::~CStatus()
{

}

SSI_INT64 CStatus::GetErrCount()
{
  return ErrCount;
}

SSI_INT64 CStatus::GetWarnCount()
{
  return WarnCount;
}

SSI_BOOL CStatus::operator ==(CStatus Other)
{
  if(State == Other.State) return 1;
  return 0;
}

void CStatus::Set(SSI_BYTE NewState, const String& NewMessage)
{
  State = NewState;
  Message = NewMessage;
  IncrementCounts();
}

//CStatus& CStatus::operator =(CStatus &Other)
//{
//	START_PROFILE("CStatus::=");
//  State = Other.State;
//  Message = Other.Message;
//  return *this;
//	STOP_PROFILE("CStatus::=");
//}

CStatus& CStatus::operator =(CStatus Other)
{
	START_PROFILE("CStatus::=");
  State = Other.State;
  Message = Other.Message;
  return *this;
	STOP_PROFILE("CStatus::=");
}


CStatus::operator SSI_BOOL()
{
  if((State == sOK) || (State == sSUCCESS))
  {
    return 1;
  }
  return 0;
}

SSI_BYTE CStatus::GetState()
{
  return State;
}

void CStatus::IncrementCounts()
{
	if(State == sERROR){
		ErrCount++;
	}
  else if(State == sWARNING) WarnCount++;
  return;
}


CStatus& CStatus::Format(SSI_BYTE inState, const SSI_CHAR *fmt, ...)
{
    SSI_INT64 Pos = -1;
    SSI_INT64 NumFields = 0;
    SSI_CHAR c;
    SSI_CHAR Temp[4096];
    String Fmt = fmt;

		State = inState;
    IncrementCounts();

		Message = "";
    //Null();

    va_list vl;

    //   szTypes is the last argument specified; all
    //   others must be accessed using the variable-
    //   argument macros.
    va_start( vl, fmt );

    // Find the %
    // Anything before the %, add to the string
    // Switch through char after the %, and scanf into temp string
    //    Check for: %d, %s, %f, %c, 
    // Continue loop until end of format string

    while((Pos = Fmt.Find("%")) >= 0)
    {
      //*this = operator+(Fmt.Left(Pos));
			Message = Message + Fmt.Left(Pos);
      Pos++;
      c = Fmt[Pos];

      union P_t
      {
        int     d;
        double  f;
        char    c;
        char   *s;
      } P;

      switch(c)
      {
      case ('d'):
        P.d = va_arg( vl, int );
        sprintf(Temp, "%d", P.d);
        Pos++;
				Message = Message + Temp;
        //*this = operator+(Temp);
        NumFields++;
        break;
      case ('f'):
        P.f = va_arg( vl, double );
        sprintf(Temp, "%f", P.f);
        Pos++;
				Message = Message + Temp;
        //*this = operator+(Temp);
        NumFields++;
        break;
      case ('c'):
        P.c = va_arg( vl, int/*char*/ );  // GNU compiler says it should be int...
        sprintf(Temp, "%c", P.c);
        Pos++;
				Message = Message + Temp;
        //*this = operator+(Temp);
        NumFields++;
        break;
      case ('s'):
        P.s = va_arg (vl, char*);
        while(*P.s)
        {
          sprintf(Temp, "%c", *P.s);
          P.s++;
					Message = Message + Temp;
          //*this = operator+(Temp);
        }
        Pos++;
        NumFields++;
        break;
      case ('%'):
        sprintf(Temp, "%%");
				Message = Message + Temp;
        //*this = operator+(Temp);
        Pos++;
        break;
      case (SSI_NULL):
        sprintf(Temp, "%%");
				Message = Message + Temp;
        //*this = operator+(Temp);
        Pos++;
        break;
      default:
        sprintf(Temp, "%c", c);
				Message = Message + Temp;
        //*this = operator+(Temp);
        Pos++;
        break;
      }
      Fmt = Fmt.Right(Fmt.GetLength() - Pos);
    }
		
		Message = Message + Fmt;
    va_end( vl );
    return *this;
}


CStatus CStatus::MakeStatus(void)
{
	return CStatus();
}

String CStatus::GetStatusMessage(void)
{
	return Message;
}

CStatus CStatus::MakeDefaultError(int LineNum, char* File)
{
	String Mess;
	Mess.Format("Internal Error: %d in %s", LineNum, File);
	CStatus Ret(sERROR, Mess, 0);
	return Ret;
}

CStatus CStatus::MakeDefaultFailure(int LineNum, char* File)
{
	String Mess;
	Mess.Format("Internal Failure: %d in %s", LineNum, File);
	CStatus Ret(sFAIL, Mess, 0);
	return Ret;
}



